Skip to content

sys/net/dhcpv6: Fixes for MUD URL option#15939

Merged
miri64 merged 3 commits intoRIOT-OS:masterfrom
namib-project:dhcp-mud-fix
Feb 10, 2021
Merged

sys/net/dhcpv6: Fixes for MUD URL option#15939
miri64 merged 3 commits intoRIOT-OS:masterfrom
namib-project:dhcp-mud-fix

Conversation

@JKRhb
Copy link
Member

@JKRhb JKRhb commented Feb 6, 2021

Contribution description

This PR fixes a couple of mistakes I made in PR #15508 which added the Manufacturer Usage Description option (MUD, RFC 8520) to the DHCPv6 client.

So far, the option was only included in Solicit Messages. According to RFC 8415, however, this is only permitted if it is "specifically allowed in the definition of individual options". I therefore removed the call of _compose_mud_url_opt from the _solicit_servers function and added it to _request_renew_rebind instead, including the option now in Request, Renew, and Rebind Messages. I updated the tests in tests/gnrc_dhcpv6_client_6lbr accordingly.

I also noticed that the naming of the Kconfig option I added in #15508 was incorrect. Setting the option DHCPV6_CLIENT_MUD_URL should now work as intended.

Furthermore, I rearranged some of the code, hopefully making the module a bit more efficient and robust. For example, the assertion of the MUD URL now happens in the dhcpv6_client_init function causing the application to crash immediately if something is wrong with the URL (rather than when a Request Message is sent).

Lastly I have noticed that the instructions for using the tests-as-root was outdated both in the readme files of tests/gnrc_dhcpv6_client_6lbr and tests/gnrc_dhcpv6_client. I edited the two files in two separate commits which could also be merged into one (especially if this information should be missing in more readmes).

Testing procedure

The changes to the client can be tested manually by using the updated tests provided in tests/gnrc_dhcpv6_client_6lbr.

The Kconfig option can be tested, for instance, by first enabling Kconfig in the Makefile of tests/gnrc_dhcpv6_client_6lbr and then changing the MUD URL by using make menuconfig. If the URL is not https://example.org anymore, performing the tests with sudo make test-as-root should fail.

Issues/PRs references

See also #15508.

@benpicco benpicco added Area: network Area: Networking Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) labels Feb 6, 2021
@benpicco
Copy link
Contributor

benpicco commented Feb 6, 2021

Please squash, let's see what Murdock thinks of this.

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 6, 2021
Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some last minute style comments ;-)

@miri64
Copy link
Member

miri64 commented Feb 8, 2021

You may squash those immediately.

If any problems are encountered (i.e. if the test prints the string `FAILED`),
set the echo parameter in the `run()` function at the bottom of the test script
(tests/01-run.py) to `True`. The test script will then offer a more detailed
(tests-as-root/01-run.py) to `True`. The test script will then offer a more detailed
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miri64 Thanks :) While I was at it I corrected the path to the test files in this line and also squashed it already. I hope that this was okay

@JKRhb JKRhb requested a review from miri64 February 9, 2021 10:13
Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running the test on samr21-xpro, I get a timeout. When checking out e0f457 (the merge base of this PR) I do not get the timeout :-/

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Details
[mlenders@sarajevo RIOT]<3 BOARD=samr21-xpro make -C tests/gnrc_dhcpv6_client_6lbr/ -j test-as-root
make: Entering directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/gnrc_dhcpv6_client_6lbr'
make[1]: Nothing to be done for 'all'.
[sudo] password for mlenders: 


make[2]: Nothing to be done for 'all'.
sudo /home/mlenders/Repositories/RIOT-OS/RIOT/dist/tools/ethos/ethos tap0 /dev/ttyACM0 115200 
----> ethos: sending hello.
----> ethos: activating serial pass through.
DHCPv6: Selecting interface 7 as upstream
main()----> ethos: hello reply received
> ifconfig
help

> 
> ifconfig
Iface  7  HWaddr: BE:D6:64:3B:38:E9 
          L2-PDU:1500  MTU:1500  HL:64  RTR  
          Source address length: 6
          Link type: wired
          inet6 addr: fe80::bcd6:64ff:fe3b:38e9  scope: link  VAL
          inet6 addr: fe80::2  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff3b:38e9
          inet6 group: ff02::1:ff00:2
          
Iface  6  HWaddr: 3C:97  Channel: 26  Page: 0  NID: 0x23  PHY: O-QPSK 
          
          Long HWaddr: 00:04:25:19:18:01:BC:97 
           TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
          AUTOACK  ACK_REQ  CSMA  L2-PDU:102  MTU:1280  HL:64  RTR  
          RTR_ADV  6LO  IPHC  
          Source address length: 8
          Link type: wireless
          inet6 addr: fe80::204:2519:1801:bc97  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff01:bc97
          
> help
Command              Description
---------------------------------------
reboot               Reboot the node
7
ifconfig 7
version              Prints current RIOT_VERSION
pm                   interact with layered PM subsystem
ps                   Prints information about running threads.
random_init          initializes the PRNG
random_get           returns 32 bit of pseudo randomness
nib                  Configure neighbor information base
ifconfig             Configure network interfaces
6ctx                 6LoWPAN context configuration tool
> ifconfig 7
Iface  7  HWaddr: BE:D6:64:3B:38:E9 
ifconfig
help
          L2-PDU:1500  MTU:1500  HL:64  RTR  
          Source address length: 6
          Link type: wired
          inet6 addr: fe80::bcd6:64ff:fe3b:38e9  scope: link  VAL
          inet6 addr: fe80::2  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff3b:38e9
          inet6 group: ff02::1:ff00:2
          
> ifconfig
Iface  7  HWaddr: BE:D6:64:3B:38:E9 
          L2-PDU:1500  MTU:1500  HL:64  RTR  
          Source address length: 6
          Link type: wired
          inet6 addr: fe80::bcd6:64ff:fe3b:38e9  scope: link  VAL
          inet6 addr: fe80::2  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff3b:38e9
          inet6 group: ff02::1:ff00:2
          
Iface  6  HWaddr: 3C:97  Channel: 26  Page: 0  NID: 0x23  PHY: O-QPSK 
          
          Long HWaddr: 00:04:25:19:18:01:BC:97 
           TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
          AUTOACK  ACK_REQ  CSMA  L2-PDU:102  MTU:1280  HL:64  RTR  
          RTR_ADV  6LO  IPHC  
          Source address length: 8
          Link type: wireless
          inet6 addr: fe80::204:2519:1801:bc97  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff01:bc97
          
> help
Command              Description
---------------------------------------
reboot               Reboot the node
ifconfig 6
version              Prints current RIOT_VERSION
pm                   interact with layered PM subsystem
ps                   Prints information about running threads.
random_init          initializes the PRNG
random_get           returns 32 bit of pseudo randomness
nib                  Configure neighbor information base
ifconfig             Configure network interfaces
6ctx                 6LoWPAN context configuration tool
> ifconfig 6
Iface  6  HWaddr: 3C:97  Channel: 26  Page: 0  NID: 0x23  PHY: O-QPSK 
          
          Long HWaddr: 00:04:25:19:18:01:BC:97 
           TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
          AUTOACK  ACK_REQ  CSMA  L2-PDU:102  MTU:1280  HL:64  RTR  
          RTR_ADV  6LO  IPHC  
          Source address length: 8
          Link type: wireless
          inet6 addr: fe80::204:2519:1801:bc97  scope: link  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff01:bc97
          
> Timeout in expect script at "child.expect(r"inet6 addr:\s+{}[0-9a-fA-F:]+\s"" (tests/gnrc_dhcpv6_client_6lbr/tests-as-root/01-run.py:179)

make: *** [/home/mlenders/Repositories/RIOT-OS/RIOT/makefiles/tests/tests.inc.mk:35: test-as-root] Error 1
make: Leaving directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/gnrc_dhcpv6_client_6lbr'

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

When running the test on samr21-xpro, I get a timeout. When checking out e0f457 (the merge base of this PR) I do not get the timeout :-/

Hmm, that is strange :/ I just ran the test on native again and it succeeded – do you see indications on why it might fail on samr21-xpro?

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Hmm, that is strange :/ I just ran the test on native again and it succeeded – do you see indications on why it might fail on samr21-xpro?

The address seems not to be configured correctly. Maybe the buffer is too small?

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

Hmm, that is strange :/ I just ran the test on native again and it succeeded – do you see indications on why it might fail on samr21-xpro?

The address seems not to be configured correctly. Maybe the buffer is too small?

Hmm, do you mean the receive buffer? Or is there another buffer that could be affected?

I just ran the tests on an ESP32 where they also passed – could you maybe try it without once more without the MUD option for a comparison? (Sorry that this small change causes so much trouble :/)

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Hmm, do you mean the receive buffer? Or is there another buffer that could be affected?

Yeah, but sadly, increasing the receive buffer did not help :-/.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

I just ran the tests on an ESP32 where they also passed – could you maybe try it without once more without the MUD option for a comparison? (Sorry that this small change causes so much trouble :/)

With everything regarding MUD options commented out, the test succeeds :-/.

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

With everything regarding MUD options commented out, the test succeeds :-/.

Hmm, very strange :/ Could you maybe run the rest with ENABLE_DEBUG 1 to see where it gets stuck?

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

With everything regarding MUD options commented out, the test succeeds :-/.

Hmm, very strange :/ Could you maybe run the rest with ENABLE_DEBUG 1 to see where it gets stuck?

Did this already, but doesn't really give helpful output. :(

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Ah, gave it another try:

DHCPv6 client: received REPLY
DHCPv6 client: message is not from my server

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

As far as I can tell, there is a buffer overflow happening somewhere that overwrites the first few bytes of server.duid.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Ahhh, I believe strncpy() is provided the wrong length!

diff --git a/sys/net/application_layer/dhcpv6/client.c b/sys/net/application_layer/dhcpv6/client.c
index ce20966dcb..052935847f 100644
--- a/sys/net/application_layer/dhcpv6/client.c
+++ b/sys/net/application_layer/dhcpv6/client.c
@@ -262,13 +262,13 @@ static inline size_t _compose_mud_url_opt(dhcpv6_opt_mud_url_t *mud_url_opt,
     uint16_t len = strlen(mud_url);
 
     if (len > len_max) {
-        assert(0);
+        assert(len <= len_max);
         return 0;
     }
 
     mud_url_opt->type = byteorder_htons(DHCPV6_OPT_MUD_URL);
     mud_url_opt->len = byteorder_htons(len);
-    strncpy(mud_url_opt->mudString, mud_url, len_max);
+    strncpy(mud_url_opt->mudString, mud_url, len);
     return len + sizeof(dhcpv6_opt_mud_url_t);
 }
 

fixes it for me! (note that the assert is optional, but I think it makes the problem clearer in case the condition of the assert() is printed).

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

This bug existed previously, but probably adding it to the other message types revealed the bug more clearly.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

also just noticed, that mudString is not in accordance with our coding conventions. We use snake_case not camelCase.

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

Thank you for identifying these issues! :) I pushed a new fixup commit with your suggestions

also just noticed, that mudString is not in accordance with our coding conventions. We use snake_case not camelCase.

You are right, back then we used the casing from the RFC which was not the right choice. This should now also be fixed :)

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK, tested in on samr21-xpro and native. Both succeed now. To be on the save side I also ran the test with make all-asan on native which yielded nothing.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Please squash! :-)

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

Done :) Thank you once more for your patience and expertise :)

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

You are right, back then we used the casing from the RFC which was not the right choice. This should now also be fixed :)

But even there it is MUDstring, so yet another variant ;-).

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

You are right, back then we used the casing from the RFC which was not the right choice. This should now also be fixed :)

But even there it is MUDstring, so yet another variant ;-).

Oh, ahem, then I made two mistakes at once – I'll try my best to bring it down to zero when I open the next PR ;)

@JKRhb
Copy link
Member Author

JKRhb commented Feb 9, 2021

Hmm, some tests on Murdock failed (see, e. g., this one). I guess this can be easily fixed by replacing strncpy with memcpy?

Edit: If so, I already provided a fixup commit below.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

Hmm, some tests on Murdock failed (see, e. g., this one). I guess this can be easily fixed by replacing strncpy with memcpy?

probably, yes. Though I'm wondering what GCC is actually trying to say with that error message ^^"

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

You can squash that already :-)

@maribu maribu added State: waiting for CI update State: The PR requires an Update to CI to be performed first and removed State: waiting for CI update State: The PR requires an Update to CI to be performed first labels Feb 9, 2021
maribu
maribu previously requested changes Feb 9, 2021
Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait for #15974 to get in and another round of Murdock afterwards before merging.

@miri64
Copy link
Member

miri64 commented Feb 9, 2021

#15974 was merged, so can you lift your block, please, @maribu?

@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Feb 9, 2021
@maribu maribu dismissed their stale review February 10, 2021 06:23

All green withnl full CI run

@miri64 miri64 merged commit 1db4800 into RIOT-OS:master Feb 10, 2021
@kaspar030 kaspar030 added this to the Release 2021.04 milestone Apr 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants